perm filename KLUDGE.WEB[PAS,DEK] blob
sn#671806 filedate 1982-08-04 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00006 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 % Here is TEX material that gets inserted after \input webhdr
C00005 00003 @* Introduction.
C00007 00004 @* Input and output.
C00012 00005 @* The main program.
C00017 00006 @* Index.
C00021 ENDMK
C⊗;
% Here is TEX material that gets inserted after \input webhdr
\def\hang{\hangindent 3em\ \unskip\!}
\chcode@@=13 \def@@{\penalty999\ } % ties words together
\def\TEX{T\hbox{\hskip-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}
\font b=cmr9 \def\mc{\:b} % medium caps for names like PASCAL
\def\PASCAL{{\mc PASCAL}}
\def\(#1){} % this is used to make module names sort themselves better
\def\9#1{} % this is used for sort keys in the index
\font D=cmtt at 15truept % font used in the title line below (only)
\font E=cmr7 at 14truept % font used in the title line below (only)
\def\title{TF\lowercase{to}PL}
\def\contentspagenumber{101}
\def\topofcontents{\topspace 0pt
\vfill
\ctrline{\:E The {\:D KLUDGE} processor}
\vfill}
\def\botofcontents{\vfill}
\setcount0 \contentspagenumber
\topofcontents
\ctrline{(replace this page by the contents page printed later)}
\botofcontents
\mark{1}\eject
@* Introduction.
This is a trivial program that converts the huge file \.{TEX.TEX} output by
\.{WEAVE} into shorter subfiles. These shorter files can be input by \TEX\
and printed on Stanford's Dover without crashing that system.
(It can't handle long jobs, so we have to break this one up.)
The program ignores whatever formatting appears at the beginning of
the file, and substitutes its own.
There is no generality. I used \.{WEB} for this only because I am afraid
{\mc SAIL} will not be available to me much longer, and because I couldn't
face programming in bare \PASCAL.
@ I've tried to write this program entirely in standard \PASCAL.
@p program KLUDGE(tex_file,hdr_file,tex1_file,tex2_file,tex3_file,tex4_file,
tex5_file,tex6_file);
var@?@<Globals in the outer block@>@/
@ Here are some macros for common programming idioms.
@d incr(#) == #←#+1 {increase a variable by unity}
@d decr(#) == #←#-1 {decrease a variable by unity}
@d do_nothing == {empty statement}
@* Input and output.
There are two input files. There are three output files.
@<Glob...@>=
@!tex_file:text; {the input}
@!hdr_file:text; {contains constant stuff for WEB formatting}
@!tex1_file:text; {first part of the output}
@!tex2_file:text; {second part of the output}
@!tex3_file:text; {third part of the output}
@!tex4_file:text; {fourth part of the output}
@!tex5_file:text; {fifth part of the output}
@!tex6_file:text; {sixth part of the output}
@ Here we open them, except for |hdr_file|.
@<Open the files@>=
reset(tex_file); rewrite(tex1_file); rewrite(tex2_file); rewrite(tex3_file);
rewrite(tex4_file); rewrite(tex5_file); rewrite(tex6_file);
@ Input goes into a buffer called |buffer|. The number of characters
in the buffer is called |buf_count|.
@<Glob...@>=
@!buffer:array[1..100] of char; {current line of input to be output}
@!buf_count:integer; {this many characters are in that line}
@!boundary:boolean; {is this a ``boundary'' line?}
@ When a \.{WEB} module begins with `\.{@@*}', the output of \.{WEAVE}
is a line beginning with \.{\\N} followed by a digit. We shall call these
{\sl boundary lines}.
The |input_ln| procedure inputs a line of |tex_file| into the input buffer
and sets |boundary| to |true| if it is a boundary line or if the file has ended.
@p procedure input_ln;
begin buf_count←0;
if eof(tex_file) then boundary←true
else begin while not eoln(tex_file) do
begin incr(buf_count); read(tex_file,buffer[buf_count]);
end;
read_ln(tex_file); boundary←false;
if buf_count>2 then if (buffer[1]='\')∧(buffer[2]='N') then
if (buffer[3]≥'0')∧(buffer[3]≤'9') then
boundary←true;
end;
end;
@ The |copy| procedure copies up to |n| ``chapters'' from |tex_file| to
a specified output file. A ``chapter'' is initiated by a boundary line.
If the input file does not end before |n| chapters have been copied, an extra
`\.{\\end}' line is written. The first line of the first chapter is
assumed to be already present in the buffer.
@p procedure copy(var f:text;@!n:integer);
var k:integer; {index into |buffer|}
begin while (n>0)∧ not eof(tex_file) do
begin @<Copy a chapter@>;
decr(n);
end;
if n=0 then write_ln(f,'\par\vfill\end');
end;
@ @<Copy a chapter@>=
repeat for k←1 to buf_count do write(f,buffer[k]);
write_ln(f);
input_ln;
until boundary;
@ Here's a procedure that outputs `\.{\\mark\{}$n$\.\}', where $n$ is the
number following `\.{\\N}' in the current boundary line.
@p procedure mark(var f:text);
var k:integer; {index into |buffer|}
begin k←3;
write(f,'\mark{');
while buffer[k]≠'.' do {the number is followed by a period}
begin write(f,buffer[k]); incr(k);
end;
write(f,'}');
end;
@ The following procedures puts constant information at the
beginning of an output file.
@p procedure copy_hdr(var f:text);
var c:char;
begin reset(hdr_file);
while not eof(hdr_file) do
begin while not eoln(hdr_file) do
begin read(hdr_file,c); write(f,c);
end;
read_ln(hdr_file); write_ln(f);
end;
end;
@* The main program.
Here is where \.{KLUDGE} begins and ends.
@p begin @<Open the files@>;
@<Pass over the initial limbo material@>;
@<Output the header for |tex1_file|@>;
copy(tex1_file,14);
@<Output the header for |tex2_file|@>;
copy(tex2_file,13);
@<Output the header for |tex3_file|@>;
copy(tex3_file,9);
@<Output the header for |tex4_file|@>;
copy(tex4_file,8);
@<Output the header for |tex5_file|@>;
copy(tex5_file,9);
@<Output the header for |tex6_file|@>;
copy(tex6_file,1000);
end.
@ @<Pass over...@>=
repeat input_ln;
until boundary
@ @<Output the header for |tex1_file|@>=
copy_hdr(tex1_file);
write_ln(tex1_file,'\open1=cont1.tex \def\sendcontents{\send1}');
write_ln(tex1_file,'\setcount0\contentspagenumber\advcount0');
write_ln(tex1_file,'\topofcontents');
write_ln(tex1_file,
'\ctrline{(replace this page by the contents page printed later)}');
write_ln(tex1_file,'\botofcontents');
write_ln(tex1_file,'\mark{1}\eject')
@ @<Output the header for |tex2_file|@>=
copy_hdr(tex2_file);
write_ln(tex2_file,'\open2=cont2.tex \def\sendcontents{\send2}');
write_ln(tex2_file,'\topofcontents');
write_ln(tex2_file,'\ctrline{(this is part 2 of a bigger file)}');
write_ln(tex2_file,'\botofcontents');
write_ln(tex2_file,'\setcount0\xxx % insert the last page number of part 1');
mark(tex2_file);
write_ln(tex2_file,'\eject')
@ @<Output the header for |tex3_file|@>=
copy_hdr(tex3_file);
write_ln(tex3_file,'\open3=cont3.tex \def\sendcontents{\send3}');
write_ln(tex3_file,'\topofcontents');
write_ln(tex3_file,'\ctrline{(this is part 3 of a bigger file)}');
write_ln(tex3_file,'\botofcontents');
write_ln(tex3_file,'\setcount0\xxx % insert the last page number of part 2');
mark(tex3_file);
write_ln(tex3_file,'\eject')
@ @<Output the header for |tex4_file|@>=
copy_hdr(tex4_file);
write_ln(tex4_file,'\open4=cont4.tex \def\sendcontents{\send4}');
write_ln(tex4_file,'\topofcontents');
write_ln(tex4_file,'\ctrline{(this is part 4 of a bigger file)}');
write_ln(tex4_file,'\botofcontents');
write_ln(tex4_file,'\setcount0\xxx % insert the last page number of part 3');
mark(tex4_file);
write_ln(tex4_file,'\eject')
@ @<Output the header for |tex5_file|@>=
copy_hdr(tex5_file);
write_ln(tex5_file,'\open5=cont5.tex \def\sendcontents{\send5}');
write_ln(tex5_file,'\topofcontents');
write_ln(tex5_file,'\ctrline{(this is part 5 of a bigger file)}');
write_ln(tex5_file,'\botofcontents');
write_ln(tex5_file,'\setcount0\xxx % insert the last page number of part 4');
mark(tex5_file);
write_ln(tex5_file,'\eject')
@ @<Output the header for |tex6_file|@>=
copy_hdr(tex6_file);
write_ln(tex6_file,
'\def\readcontents{\input cont1 \input cont2 \input cont3',
' \input cont4 \input cont5 \input contents }');
write_ln(tex6_file,'\topofcontents');
write_ln(tex6_file,'\ctrline{(this is part 6 of a bigger file)}');
write_ln(tex6_file,'\botofcontents');
write_ln(tex6_file,'\setcount0\xxx % insert the last page number of part 5');
mark(tex6_file);
write_ln(tex6_file,'\eject')
@* Index.